﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
//
using CommonClass;
using ControlLib;
using System.Diagnostics;
using EncryptProject;
using System.Security.AccessControl;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Configuration;
using WebAppProject.WCF.webAppService;
using SoftKeyLib;
using SurveillanceLib;
using CommonBase;
using DAL;


namespace MatrixManagement
{
    /// <summary>
    /// 主界面
    /// </summary>
    public partial class frm_Main : Form
    {
        #region 常量

        /// <summary>
        /// 默认每个大屏分割为 4 个视频窗口
        /// </summary>
        const int PANEL_COUNT = 4;

        /// <summary>
        /// 系统大屏信息
        /// </summary>
        const string MSG_WALLINFO = "系统检测到 {0} 个大屏";

        /// <summary>        
        /// 系统视频窗口信息
        /// </summary>
        const string MSG_PANELINFO = "共分为 {0} 个视频窗口";

        /// <summary>
        /// 大屏设置信息
        /// </summary>
        const string MSG_SETINFO = "已设置 {0} 个；未设置 {1} 个";

        #endregion

        #region 变量

        DataRow drSystem = null; // SystemInformation 表的信息【只含唯一一条记录】
        SoftKeyOperation keyOperation = new SoftKeyOperation();
        VWMSDal dataOperation4VWMS = new VWMSDal(); // 操作数据库
        SurveillanceDAL dataOperation4Surveillance = new SurveillanceDAL(); // 操作数据库
        SplitScreen splitScreen = new SplitScreen(); // 定义简单分屏，需要进一步加工
        PanelOperation panelOperation = new PanelOperation(); // 定义内部视频系统分屏【显示视频】，无返回值
        PanelOperationExt panelOperationExt = new PanelOperationExt(); // 定义外部预览界面分屏【颜色提示】，返回分屏列表
        frm_AutoSplitWall[] autoSplitWalls; // 记录上墙大屏数，用于对大屏的销毁，注：第一个元素未用，因为其为主界面，并非大屏

        List<Panel> panelNewCurrentList = null; // 记录最新的该上墙分屏列表
        int currentWallIndex = -1; // 记录当前大屏序号

        Timer timer = new Timer(); // 计时器
        bool isBlink = true; // 图标闪烁使用
        int wallCount; // 实际大屏总数
        int initialWallIndex; // 上墙大屏开始下标

        #endregion

        #region 构造函数

        public frm_Main()
        {
            InitializeComponent();

            #region Timer
            timer.Interval = 1000; // 单位：毫秒
            timer.Tick += (s, e) =>
            {
                blinkImage(isBlink);
            };
            #endregion
        }

        #endregion

        #region 方法

        #region 初始化操作
        /// <summary>
        /// 获取数据库名称
        /// </summary>
        private void initializeDatabaseName()
        {
            Utilities.DatabaseName = "db_VWMS";
        }

        /// <summary>
        /// 获取本项目 GUID
        /// </summary>
        private void initializeProjectGUID()
        {
            Utilities.ProjectGUID = Utilities.GetProjectGUID();
        }

        /// <summary>
        /// 获取 WCF 地址
        /// </summary>
        private void initializeWcfURL()
        {
            WcfConfig.WcfServcieUrl4WebAppService = ConfigurationManager.AppSettings["WcfServcieUrl4WebAppService"];
        }

        /// <summary>
        /// 初始化加密狗
        /// </summary>
        /// <returns>true: 正式版用户；false: 试用版用户</returns>
        private bool initializeSoftKey()
        {
            try
            {
                string title;
                bool isRegUser = Utilities.CheckSoftKey4User(dataOperation4Surveillance.GetDataSet(
                    string.Format(SurveillanceDAL.QUERY_GET_ALLSYSTEMDATA_BYID, SurveillanceDAL.SYSTEM_GUID),
                    string.Empty, "db_VWMSConnectionString", string.Format("{0}.exe", Application.ProductName)),
                    this.Handle, out drSystem, out title, keyOperation);
                this.Text += title; // 最终标题

                return isRegUser;
            }
            catch (Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }

            return false;
        }

        /// <summary>
        /// 保存最新数据到 SystemInformation 表中
        /// </summary>
        private void initializeDatabase4SystemInformation()
        {
            if (drSystem != null && dataOperation4Surveillance != null)
            {
                int result = dataOperation4Surveillance.EditSystemItem(drSystem, 
                    dataOperation4Surveillance); // 保存数据
                if (result > 0)
                {
#if DEBUG
                    Debug.WriteLine("操作成功：保存最新数据到 SystemInformation 表中");
#endif
                }
                else
                {
#if DEBUG
                    Debug.WriteLine("操作失败：保存最新数据到 SystemInformation 表中");
#endif
                }
            }
        }

        /// <summary>
        /// 初始化文件权限，增加 Users 用户对 mdb 文件的修改权限
        /// </summary>
        private void initializeFileAccessControl()
        {
            Utilities.ChangeDBFileAccessControl(Utilities.DatabaseName);
        }

        /// <summary>
        /// 读写机器码【注册表与 ini 文件】，并判断试用次数，正式版用户继续使用
        /// </summary>
        /// <param name="isRegUser">true: 正式版用户；false: 试用版用户</param>
        /// <returns>试用完毕与否</returns>
        private bool initializeSystemTrialTimes(bool isRegUser)
        {
            return Utilities.CheckTrialTimes(isRegUser, drSystem, Utilities.DatabaseName,
                changeControlButtonDisenableStateWhenException);
        }

        /// <summary>
        /// 初始化数据库，判定是否可以正常连接到数据库
        /// </summary>
        /// <returns>返回数据库中保存的大屏信息</returns>
        private DataTable initializeDatabase()
        {
            return Utilities.GetDataTable(VWMSDal.QUERY_GET_ALLWALLDATA);
        }

        /// <summary>
        /// 初始化显示已保存的大屏
        /// </summary>
        /// <param name="dtWall">所有已保存的大屏信息</param>
        private List<WallInformationModel> initializeWallLoaded(DataTable dtWall)
        {
            if (dtWall == null ||
                (dtWall != null && dtWall.Rows == null) ||
                (dtWall != null && dtWall.Rows != null && dtWall.Rows.Count <= 0)) // 判断是否存在大屏信息
                return null;

            List<WallInformationModel> savedWallList = new List<WallInformationModel>();
            WallInformationModel wallModel;
            int outIndex;

            foreach (DataRow savedSingleWall in dtWall.Rows)
            {
                wallModel = new WallInformationModel()
                {
                    WallIndex = int.TryParse(savedSingleWall["WallIndex"].ToString(), out outIndex) ? outIndex : -1,
                    PanelIndex = int.TryParse(savedSingleWall["PanelIndex"].ToString(), out outIndex) ? outIndex : -1,
                    IP = savedSingleWall["IP"].ToString(),
                    Port = savedSingleWall["Port"].ToString(),
                    Type = savedSingleWall["Type"].ToString(),
                    Channel = savedSingleWall["Channel"].ToString(),
                    UserName = savedSingleWall["UserName"].ToString(),
                    UserPwd = savedSingleWall["UserPwd"].ToString(),
                };

                savedWallList.Add(wallModel);
            }

            return savedWallList;
        }

        /// <summary>
        /// 初始化统计界面
        /// </summary>
        private void initializeStatistics()
        {
            WallPreview preWall;
            TagModel preWallPanelTag;
            int outChannelNo;
            DataTable dt = new DataTable();

            dt.Columns.Add("大屏序号");
            dt.Columns.Add("是否上墙");
            dt.Columns.Add("视频序号");
            dt.Columns.Add("IP");
            dt.Columns.Add("通道号");

            if (panelAllWall.Controls != null && panelAllWall.Controls.Count > 0)
            {
                for (int i = 0; i < panelAllWall.Controls.Count; i++)
                {
                    if (panelAllWall.Controls[i] != null &&
                        panelAllWall.Controls[i] is WallPreview &&
                        (panelAllWall.Controls[i] as WallPreview).PanelCurrentList != null &&
                        (panelAllWall.Controls[i] as WallPreview).PanelCurrentList.Count > 0 &&
                        (panelAllWall.Controls[i] as WallPreview).Tag != null &&
                        (panelAllWall.Controls[i] as WallPreview).Tag is TagModel)
                    {
                        preWall = panelAllWall.Controls[i] as WallPreview;
                        for (int j = 0; j < preWall.PanelCurrentList.Count; j++)
                        {
                            if (preWall.PanelCurrentList[j] != null &&
                                preWall.PanelCurrentList[j].Tag != null &&
                                preWall.PanelCurrentList[j].Tag is TagModel)
                            {
                                preWallPanelTag = preWall.PanelCurrentList[j].Tag as TagModel;
                                if (int.TryParse(preWallPanelTag.Panel_SelectedChannel, out outChannelNo))
                                {
                                    dt.Rows.Add(string.Format("大屏 {0}", i + 1),
                                        preWall.IsShowWall == true ? "是" : "否",
                                        string.Format("视频 {0}", j + 1),
                                        string.Format("{0}:{1}", preWallPanelTag.Driver_IP, preWallPanelTag.Driver_Port).Trim(':'),
                                        string.Format("通道 {0}", outChannelNo + 1));
                                }
                                else
                                {
                                    dt.Rows.Add(string.Format("大屏 {0}", i + 1),
                                        preWall.IsShowWall == true ? "是" : "否",
                                        string.Format("视频 {0}", j + 1),
                                        string.Format("{0}:{1}", preWallPanelTag.Driver_IP, preWallPanelTag.Driver_Port).Trim(':'),
                                        preWallPanelTag.Panel_SelectedChannel);
                                }
                            }
                        }
                    }
                }
            }

            this.gridStatistics.DataSource = dt;
            this.gridStatistics.MergeColumnNames.Add("columnWallIndex");
            this.gridStatistics.MergeColumnNames.Add("columnIsShow");
            //this.gridStatistics.AddSpanHeader(2, 3, "视频信息"); // 合并表头
        }

        /// <summary>
        /// 初始化布局
        /// </summary>
        private void initializeLayout()
        {
            this.WindowState = FormWindowState.Maximized; // 窗口最大化
            panelLeft.Size = new Size(202, 484); // Tree 宽度
            tabWall.SelectedIndex = 0; // 第一个选项卡选中
        }

        /// <summary>
        /// 初始化文字操作
        /// </summary>
        /// <returns>是否能执行上墙操作</returns>
        private bool initializeText()
        {
            lbWallInfo.ForeColor = Color.Black; // 正常颜色


            if (Utilities.DebugModel)
            {
                wallCount = Screen.AllScreens.Length; // 所有大屏总数
                initialWallIndex = 0;
            }
            else
            {
                wallCount = Screen.AllScreens.Length - 1; // 实际大屏总数【即：所有大屏数 - 1】
                initialWallIndex = 1;
            }


            if (wallCount <= 0)
            {
                changeControlButtonDisenableStateWhenException("目前只有 1 个大屏，无法执行上墙操作！");
                return false;
            }

            lbWallInfo.Text = string.Format(MSG_WALLINFO, wallCount); // 大屏数
            lbPanelInfo.Text = string.Format(MSG_PANELINFO, wallCount * PANEL_COUNT); // 视频窗口数
            lbSetInfo.Text = string.Format(MSG_SETINFO, 0, wallCount * PANEL_COUNT); // 已设置、未设置数

            return true;
        }

        /// <summary>
        /// 初始化树操作
        /// </summary>
        private void initializeTree()
        {
            treeView1.Nodes.Clear();
            TreeViewOperation _treeOpertion = new TreeViewOperation()
            {
                TreeViewRoot = treeView1, // 递归函数，0 为根节点的父节点 ParentID 的值
                DisConnectAction = disConnectEvent,
            };
            _treeOpertion.AddTreeView(0, (TreeNode)null); // 获取树节点
        }

        /// <summary>
        /// 初始化大屏预览模块操作【在数据库中已存在保存的大屏】
        /// </summary>
        /// <param name="savedWallList">在数据库中已保存的所有大屏信息</param>
        private void initializeWallPreview(List<WallInformationModel> savedWallList)
        {
            if (savedWallList == null)
                throw new Exception("该方法仅用于数据库中已保存大屏信息的情况！");

            List<WallInformationModel> singleWallList = new List<WallInformationModel>(); // 记录单个大屏信息
            Dictionary<string, string> ip2loginIDDic = new Dictionary<string, string>(); // 记录 ip:port -- LoginID，用于保存设备登录 ID
            NetDeviceInfoStruct deviceInfo; // 设备用户信息获得
            int error = 0, okSum = 0;
            string pLoginID; // 登录 ID
            WallPreview preview;
            Panel inforPanel;
            List<Panel> panelInforList = new List<Panel>();
            IList<Rectangle> rectList = splitScreen.CalcPanelRectangle(wallCount, panelAllWall.Size); // 得到各个大屏的创建位置

            panelAllWall.Controls.Clear(); // 清空所有预览大屏
            for (int i = 0; i < rectList.Count; i++)
            {
                okSum = 0; // 记录该大屏的已成功设置个数
                singleWallList.Clear();
                // 1. 获得单个大屏信息
                foreach (WallInformationModel singleWall in savedWallList)
                {
                    if (singleWall.WallIndex == i &&
                        singleWall.PanelIndex != -1 &&
                        !string.IsNullOrWhiteSpace(singleWall.IP) &&
                        !string.IsNullOrWhiteSpace(singleWall.Port) &&
                        !string.IsNullOrWhiteSpace(singleWall.Channel) &&
                        !string.IsNullOrWhiteSpace(singleWall.UserName) &&
                        !string.IsNullOrWhiteSpace(singleWall.UserPwd) &&
                        !string.IsNullOrWhiteSpace(singleWall.Type)) // 是否是对应大屏，获取登录 ID
                    {
                        singleWall.DriverInstance = DriverFactory.Factory.CreateDriver(singleWall.Type); // 创建设备实例

                        if (!ip2loginIDDic.ContainsKey(string.Format("{0}:{1}", singleWall.IP, singleWall.Port))) // 判断是否存在已登录的设备
                        {
                            pLoginID = singleWall.DriverInstance.Login(singleWall.IP, ushort.Parse(singleWall.Port),
                                singleWall.UserName,
                                EncryptAlgorithmHelper.Decrypt2(singleWall.UserPwd, Utilities.MachineCode),
                                out deviceInfo, out error); // 设备用户登录
                            if (!string.IsNullOrWhiteSpace(pLoginID))
                            {
                                singleWall.IsLoginSuccessful = true; // 设备成功登录
                                singleWall.LoginID = pLoginID;
                                okSum++;

                                ip2loginIDDic.Add(string.Format("{0}:{1}", singleWall.IP, singleWall.Port), pLoginID);
                            }
                            else
                            {
                                singleWall.IsLoginSuccessful = false; // 设备登录失败
                                singleWall.LoginID = string.Empty;
                            }
                        }
                        else // 存在已登录的设备，直接获取登录 ID
                        {
                            singleWall.IsLoginSuccessful = true; // 设备成功登录
                            singleWall.LoginID = ip2loginIDDic[string.Format("{0}:{1}", singleWall.IP, singleWall.Port)];
                            okSum++;
                        }
                    }

                    if (singleWall.WallIndex == i) // 是否是对应大屏
                        singleWallList.Add(singleWall);
                }

                // 2. 创建 List<Panel>，用于预览窗口中 ToolTip 及颜色的显示
                panelInforList.Clear();
                foreach (WallInformationModel singleWall in singleWallList)
                {
                    inforPanel = new Panel()
                    {
                        Tag = new TagModel()
                        {
                            Driver_IP = singleWall.IP,
                            Panel_SelectedChannel = singleWall.Channel,
                            Driver_IsLogin = !string.IsNullOrWhiteSpace(singleWall.LoginID), // 设备登录状态
                        },
                    };

                    panelInforList.Add(inforPanel);
                }

                preview = new WallPreview(showEditWallDetail, showWall, closeWall) // 3. 创建大屏预览模块
                {
                    Width = rectList[i].Width,
                    Height = rectList[i].Height,
                    Left = rectList[i].Left,
                    Top = rectList[i].Top,
                    Tag = new TagModel()
                    {
                        Wall_Index = i, // 表示第几个大屏
                        Wall_IsShow = false, // 未上墙显示
                    },


                    WallNo = (i + 1).ToString(),
                    OKSum = okSum.ToString(),
                    FaultySum = (singleWallList.Count - okSum).ToString(),
                    IsShowWall = false,
                };

                preview.TablePanel.SuspendLayout();
                panelAllWall.SuspendLayout();
                this.SuspendLayout();

                panelOperationExt.IsHideClickEvent = panelOperationExt.IsHideBorder = true; // 隐藏边框颜色、隐藏点击事件
                preview.PanelCurrentList = panelOperationExt.SplitScreens(singleWallList.Count,
                    preview.TablePanel, null, preview.ShowButtons, panelInforList, true, toolTip); // 4. 根据数据库中已保存的大屏信息创建分屏

                panelAllWall.Controls.Add(preview);

                preview.TablePanel.ResumeLayout();
                panelAllWall.ResumeLayout();
                this.ResumeLayout();

                // 5. 设置相关 PanelTag
                if (preview.PanelCurrentList != null && preview.PanelCurrentList.Count > 0 &&
                    singleWallList != null && singleWallList.Count > 0)
                {
                    TagModel panelTag;
                    for (int j = 0; j < preview.PanelCurrentList.Count; j++)
                    {
                        if (preview.PanelCurrentList[j].Tag != null &&
                            preview.PanelCurrentList[j].Tag is TagModel &&
                            singleWallList[j] != null &&
                            !string.IsNullOrWhiteSpace(singleWallList[j].LoginID))
                        {
                            panelTag = preview.PanelCurrentList[j].Tag as TagModel;
                            panelTag.Driver_IsLogin = singleWallList[j].IsLoginSuccessful;
                            panelTag.Driver_Instance = singleWallList[j].DriverInstance;
                            panelTag.Driver_IP = singleWallList[j].IP;
                            panelTag.Driver_LoginID = singleWallList[j].LoginID;
                            panelTag.Driver_Password = singleWallList[j].UserPwd;
                            panelTag.Driver_Port = singleWallList[j].Port;
                            panelTag.Driver_Type = singleWallList[j].Type;
                            panelTag.Driver_User = singleWallList[j].UserName;
                            panelTag.Panel_SelectedChannel = singleWallList[j].Channel;
                        }
                    }
                }
            }

            SurveillanceUtilities.PanelAllWall = panelAllWall;
            updateText(); // 更新文字信息
        }

        /// <summary>
        /// 初始化大屏预览模块操作【第一次运行程序时 | 重置时】
        /// </summary>
        private void initializeWallPreview()
        {
            IList<Rectangle> rectList = splitScreen.CalcPanelRectangle(wallCount, panelAllWall.Size); // 得到各个大屏的创建位置
            panelAllWall.Controls.Clear(); // 清空所有预览大屏

            for (int i = 0; i < rectList.Count; i++)
            {
                WallPreview preview = new WallPreview(showEditWallDetail, showWall, closeWall) // 创建大屏预览模块
                {
                    Width = rectList[i].Width,
                    Height = rectList[i].Height,
                    Left = rectList[i].Left,
                    Top = rectList[i].Top,
                    Tag = new TagModel()
                    {
                        Wall_Index = i, // 表示第几个大屏
                        Wall_IsShow = false, // 未上墙显示
                    },


                    WallNo = (i + 1).ToString(),
                    OKSum = "0",
                    FaultySum = PANEL_COUNT.ToString(),
                    IsShowWall = false,
                };

                preview.TablePanel.SuspendLayout();
                panelAllWall.SuspendLayout();
                this.SuspendLayout();

                panelOperationExt.IsHideClickEvent = panelOperationExt.IsHideBorder = true; // 隐藏边框颜色、隐藏点击事件
                preview.PanelCurrentList = panelOperationExt.SplitScreens(PANEL_COUNT,
                    preview.TablePanel, null, preview.ShowButtons, null, true, toolTip); // 创建分屏

                panelAllWall.Controls.Add(preview);

                preview.TablePanel.ResumeLayout();
                panelAllWall.ResumeLayout();
                this.ResumeLayout();
            }

            SurveillanceUtilities.PanelAllWall = panelAllWall;
        }

        /// <summary>
        /// 初始化大屏上墙显示操作
        /// </summary>
        private void initializeAutoSplitWall()
        {
            autoSplitWalls = new frm_AutoSplitWall[Screen.AllScreens.Length]; // 大屏个数
            for (int i = initialWallIndex; i < autoSplitWalls.Length; i++)
            {
                autoSplitWalls[i] = initializeSingleWall(i);
            }
        }

        /// <summary>
        /// 初始化大屏
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private frm_AutoSplitWall initializeSingleWall(int index)
        {
            return new frm_AutoSplitWall(removeFromAutoSplitWalls) // 初始化大屏
            {
                StartPosition = FormStartPosition.Manual,
                Location = new Point(Screen.AllScreens[index].Bounds.Left,
                    Screen.AllScreens[index].Bounds.Top),
                Text = string.Format("大屏 {0}", index), // 任务栏标题
                Tag = new TagModel()
                {
                    Wall_Index = index, // 大屏序号
                    Wall_IsShow = false, // 未上墙
                },
            };
        }
        #endregion

        #region Timer
        /// <summary>
        /// 闪烁图片
        /// </summary>
        /// <param name="isShow"></param>
        private void blinkImage(bool isShow)
        {
            if (isShow)
                panelNotifyIcon.BackgroundImage = Image.FromFile(@".\Image\BlueDot.png");
            else
                panelNotifyIcon.BackgroundImage = Image.FromFile(@".\Image\SkyDot.png");

            isBlink = !isShow;
        }

        /// <summary>
        /// 起动计时器
        /// </summary>
        private void StartTimer()
        {
            timer.Start();
        }

        /// <summary>
        /// 停止计时器
        /// </summary>
        private void StopTimer()
        {
            timer.Stop();
            panelNotifyIcon.BackgroundImage = Image.FromFile(@".\Image\RedDot.png");
        }
        #endregion

        #region 按钮状态
        /// <summary>
        /// 控制按钮状态不可用
        /// <para>用于系统异常时情况</para>
        /// <param name="exceptionInformation">异常消息</param>
        /// </summary>
        private void changeControlButtonDisenableStateWhenException(string exceptionInformation)
        {
            tabWall.SelectedIndex = 1;
            lbWallInfo.ForeColor = Color.Red; // 异常颜色
            lbWallInfo.Text = exceptionInformation;
            btnShow.Enabled = btnReset.Enabled = btnModify.Enabled = false;  // 上墙、重置、关闭按钮不可用
            MessageBox.Show(lbWallInfo.Text, ConstantString.MSG_COMPANY);
        }

        /// <summary>
        /// 所有按钮可用
        /// <para>用于分屏前的初始化状态</para>
        /// </summary>
        /// <param name="isSplitEvent">是否是分屏操作</param>
        private void changeScreenButtonEnableState(bool isSplitEvent)
        {
            changeGroupButtonState(false);

            if (isSplitEvent)
                panelOperation.SetNull2SelectedPanel(); // 未选中任何 Panel

            // 设置上一屏按钮状态
            if (currentWallIndex <= 0)
                btnPreviousWall.Enabled = false;
            // 设置下一屏按钮状态
            if (currentWallIndex >= panelAllWall.Controls.Count - 1)
                btnNextWall.Enabled = false;
        }

        /// <summary>
        /// 除了“返回”、“上一屏”、“下一屏”，所有按钮不可用
        /// <para>用于已在大屏上显示的情况</para>
        /// </summary>
        private void changeScreenButtonDisenableState()
        {
            // 所有分屏按钮与保存按钮不可用
            btnScreen1.Enabled = btnScreen4.Enabled = btnScreen9.Enabled = btnScreen16.Enabled =
                btnSaveWall.Enabled = btnSaveAndReturnWall.Enabled = false;
            // 其它按钮可用
            btnReturnWall.Enabled = btnPreviousWall.Enabled = btnNextWall.Enabled = true;
        }

        /// <summary>
        /// 修改所有按钮的状态
        /// <para>用于最大化、还原的情况</para>
        /// </summary>
        /// <param name="isMaxScreen">是否最大化显示视频</param>
        private void changeGroupButtonState(bool isMaxScreen)
        {
            btnScreen1.Enabled = btnScreen4.Enabled = btnScreen9.Enabled = btnScreen16.Enabled =
                btnSaveWall.Enabled = btnSaveAndReturnWall.Enabled = btnReturnWall.Enabled =
                btnPreviousWall.Enabled = btnNextWall.Enabled = !isMaxScreen;
        }
        #endregion

        #region 视频相关
        /// <summary>
        /// 将焦点循环移动到下一个视频窗口中
        /// </summary>
        private void focus2NextPanel()
        {
            if (panelNewCurrentList != null &&
                PanelOperation.SelectedPanel != null &&
                PanelOperation.SelectedPanel.Tag != null &&
                PanelOperation.SelectedPanel.Tag is TagModel &&
                (PanelOperation.SelectedPanel.Tag as TagModel).Panel_Index >= 0)
            {
                int nextPanelIndex;

                TagModel selectedPanelTag = PanelOperation.SelectedPanel.Tag as TagModel;
                if (selectedPanelTag.Panel_Index + 1 >= panelNewCurrentList.Count)
                {
                    nextPanelIndex = 0; // 回到第一个视频窗口
                }
                else
                {
                    nextPanelIndex = selectedPanelTag.Panel_Index + 1; // 下一个视频窗口
                }

                PanelOperation.SelectedPanel = panelNewCurrentList[nextPanelIndex];
                panelSplitScreen.Refresh();  // 重刷界面：将边框颜色重置
                Utilities.PaintPanelBorder(PanelOperation.SelectedPanel, Color.LightGreen, 2, ButtonBorderStyle.Solid); // 绘制边框
            }
        }

        /// <summary>
        /// 播放全部 Panel【no use】
        /// </summary>
        /// <param name="playPanel">播放列表</param>
        private void realPlay(List<Panel> playPanel)
        {
            if (playPanel == null)
                return;

            int outChannel;
            foreach (Panel singleScreen in playPanel)
            {
                if (singleScreen.Tag != null &&
                    singleScreen.Tag is TagModel &&
                    (singleScreen.Tag as TagModel).Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace((singleScreen.Tag as TagModel).Driver_LoginID) &&
                    !string.IsNullOrWhiteSpace((singleScreen.Tag as TagModel).Panel_SelectedChannel) &&
                    int.TryParse((singleScreen.Tag as TagModel).Panel_SelectedChannel, out outChannel))
                {
                    TagModel tag = singleScreen.Tag as TagModel;
                    tag.Panel_RealPlayHandle = tag.Driver_Instance.RealPlay(tag.Driver_LoginID, outChannel, singleScreen.Handle);
                }
            }
        }

        /// <summary>
        /// 停止全部 Panel
        /// </summary>
        /// <param name="playPanel">停止列表</param>
        private void stopRealPlay(List<Panel> stopPanel)
        {
            if (stopPanel == null)
                return;

            foreach (Panel singleScreen in stopPanel)
            {
                if (singleScreen.Tag != null &&
                    singleScreen.Tag is TagModel &&
                    (singleScreen.Tag as TagModel).Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace((singleScreen.Tag as TagModel).Panel_RealPlayHandle))
                {
                    TagModel tag = singleScreen.Tag as TagModel;
                    if (tag.Driver_Instance.StopRealPlay(tag.Panel_RealPlayHandle)) // 停止实时监控，需要传递实时监控句柄
                        tag.Panel_RealPlayHandle = string.Empty;
                    else
                    {
                        MessageBox.Show(SurveillanceUtilities.STOP_REALPLAY_FAILURE, ConstantString.MSG_COMPANY);
                        return;
                    }
                }
            }
        }

        /// <summary>
        /// 自动保存未保存的视频，并停止播放
        /// </summary>
        private void autoSaveAndStopRealPlay()
        {
            btnSaveWall.PerformClick(); // 自动保存
            stopRealPlay(panelNewCurrentList);
        }

        /// <summary>
        /// 将当前大屏的所有 Panel_RealPlayHandle 置为空
        /// </summary>
        /// <param name="indexWall">大屏序号</param>
        private void setNonPanelRealPlayHandle4CurrentWall(int indexWall)
        {
            if (indexWall >= 0 &&
                panelAllWall.Controls != null &&
                panelAllWall.Controls.Count > 0 &&
                panelAllWall.Controls[indexWall] != null &&
                panelAllWall.Controls[indexWall] is WallPreview &&
                (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList != null &&
                (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList.Count > 0)
            {
                for (int i = 0; i < (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList.Count; i++)
                {
                    if ((panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList[i] != null &&
                        (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList[i].Tag != null &&
                        (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList[i].Tag is TagModel)
                    {
                        TagModel tag = (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList[i].Tag as TagModel;
                        tag.Panel_RealPlayHandle = string.Empty;
                    }
                }
            }
        }

        /// <summary>
        /// 将所有大屏的所有 Panel_RealPlayHandle 置为空
        /// </summary>
        private void setNonPanelRealPlayHandle4AllWall()
        {
            if (panelAllWall.Controls == null ||
                (panelAllWall.Controls != null && panelAllWall.Controls.Count <= 0))
                return;

            for (int i = 0; i < panelAllWall.Controls.Count; i++)
            {
                setNonPanelRealPlayHandle4CurrentWall(i);
            }
        }

        /// <summary>
        /// 停止最大化窗口中的视频
        /// </summary>
        private void stopMaxScreenRealPlay()
        {
            if (panelMaxScreen.Visible)
            {
                panelSplitScreen.Visible = true;
                panelMaxScreen.Visible = !panelSplitScreen.Visible;

                if (panelMaxScreen.Tag != null &&
                    panelMaxScreen.Tag is TagModel &&
                    (panelMaxScreen.Tag as TagModel).Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace((panelMaxScreen.Tag as TagModel).Panel_RealPlayHandle))
                {
                    TagModel tagMaxPanel = panelMaxScreen.Tag as TagModel;
                    if (tagMaxPanel.Driver_Instance.StopRealPlay(tagMaxPanel.Panel_RealPlayHandle)) // 停止实时监控，需要传递实时监控句柄
                        tagMaxPanel.Panel_RealPlayHandle = string.Empty;
                    else
                    {
                        MessageBox.Show(SurveillanceUtilities.STOP_REALPLAY_FAILURE, ConstantString.MSG_COMPANY);
                        return;
                    }
                }
            }
        }

        /// <summary>
        /// 停止指定窗口中的视频
        /// </summary>
        /// <param name="currPanel"></param>
        private void stopPanelRealPlay(Panel currPanel)
        {
            if (currPanel != null &&
                currPanel.Tag != null &&
                currPanel.Tag is TagModel &&
                (currPanel.Tag as TagModel).Driver_Instance != null &&
                !string.IsNullOrWhiteSpace((currPanel.Tag as TagModel).Panel_RealPlayHandle))
            {
                TagModel tagCurrentPanel = currPanel.Tag as TagModel;
                if (tagCurrentPanel.Driver_Instance.StopRealPlay(tagCurrentPanel.Panel_RealPlayHandle)) // 停止实时监控，需要传递实时监控句柄
                {
                    tagCurrentPanel.Panel_SelectedChannel = tagCurrentPanel.Panel_RealPlayHandle = string.Empty;

                    toolTip.SetToolTip(currPanel, string.Empty); // 清空 ToolTip
                    currPanel.Refresh(); // 刷新
                }
                else
                {
                    MessageBox.Show(SurveillanceUtilities.STOP_REALPLAY_FAILURE, ConstantString.MSG_COMPANY);
                    return;
                }
            }
        }
        #endregion

        #region 大屏相关
        /// <summary>
        /// 设备断开连接处理
        /// </summary>
        /// <param name="lLoginID"></param>
        /// <param name="pchDVRIP"></param>
        /// <param name="nDVRPort"></param>
        /// <param name="dwUser"></param>
        private void disConnectEvent(int lLoginID, StringBuilder pchDVRIP,
            int nDVRPort, IntPtr dwUser)
        {
            MessageBox.Show("设备用户断开连接！", ConstantString.MSG_COMPANY);
        }

        /// <summary>
        /// 显示编辑详情界面
        /// </summary>
        /// <param name="indexWall">大屏序号</param>
        private void showEditWallDetail(int indexWall)
        {
            if (indexWall < 0)
                return;

            currentWallIndex = indexWall; // 记录当前大屏序号
            //////////////////////////////////////////////////////////////////////////
            // 请注意，在设计上：panelEditWallDetail 与 panelAllWall 不能作为任意两者的停靠。
            //////////////////////////////////////////////////////////////////////////
            panelEditWallDetail.Visible = true; // 编辑详情界面可见
            panelAllWall.Visible = !panelEditWallDetail.Visible;
            panelNewCurrentList = (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList; // 将当前分屏设为最新分屏

            // 显示分屏
            if (panelAllWall.Controls[indexWall] != null &&
                panelAllWall.Controls[indexWall] is WallPreview &&
                (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList != null &&
                (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList.Count > 0) // 已存在分屏情况
            {
                WallPreview preview = panelAllWall.Controls[indexWall] as WallPreview;

                // 1. 显示对应的分屏
                switch (preview.PanelCurrentList.Count)
                {
                    case 1:
                        btnScreen1_Click(btnScreen1, null); // 这里不能用 PerformClick，因为若已经为单画面状态时，PerformClick 不会触发 btnScreen1_Click 事件
                        break;
                    case 4:
                        btnScreen4_Click(btnScreen4, null);
                        break;
                    case 9:
                        btnScreen9_Click(btnScreen9, null);
                        break;
                    case 16:
                        btnScreen16_Click(btnScreen16, null);
                        break;


                    default:
                        btnScreen4_Click(btnScreen4, null);
                        break;
                }
            }
            else
            {
                btnScreen4_Click(btnScreen4, null); // 默认分 4 分屏
            }

            // 2. 显示大屏序号
            lbWallNo.Text = (indexWall + 1).ToString();
            // 3. 更新图片状态
            if (panelAllWall.Controls[indexWall] != null &&
                 panelAllWall.Controls[indexWall] is WallPreview &&
                (panelAllWall.Controls[indexWall] as WallPreview).Tag != null)
            {
                TagModel wallTag = (panelAllWall.Controls[indexWall] as WallPreview).Tag as TagModel;

                if (wallTag.Wall_IsShow) // 已在大屏上显示
                {
                    StartTimer();
                    changeScreenButtonDisenableState(); // 设置按钮可见性
                }
                else // 未在大屏上显示
                {
                    StopTimer();
                }
            }

            // 4. 设置上一屏按钮状态
            if (indexWall <= 0)
                btnPreviousWall.Enabled = false;
            // 5. 设置下一屏按钮状态
            if (indexWall >= panelAllWall.Controls.Count - 1)
                btnNextWall.Enabled = false;

            // 默认选中第一个视频窗口
            if (panelNewCurrentList != null && panelNewCurrentList.Count > 0)
            {
                PanelOperation.SelectedPanel = panelNewCurrentList[0];
                panelSplitScreen.Refresh();  // 重刷界面：将边框颜色重置
                Utilities.PaintPanelBorder(PanelOperation.SelectedPanel, Color.LightGreen, 2, ButtonBorderStyle.Solid); // 绘制边框
            }
        }

        /// <summary>
        /// 上墙显示
        /// </summary>
        /// <param name="indexWall">上墙大屏序号</param>
        private void showWall(int indexWall)
        {
            if (indexWall < 0)
                return;

            //////////////////////////////////////////////////////////////////////////
            // 注：对于大屏已上墙时，不必再次执行上墙操作，
            //     预览模块 + 1 = 对应上墙大屏
            //////////////////////////////////////////////////////////////////////////

            if (autoSplitWalls[indexWall] == null) // 大屏已销毁时，即已关闭
            {
                autoSplitWalls[indexWall] = initializeSingleWall(indexWall);
            }

            int preWallIndex; // 大屏所对应的预览模块序号


            if (Utilities.DebugModel)
            {
                preWallIndex = indexWall;
            }
            else
            {
                preWallIndex = indexWall - 1;
            }


            if (preWallIndex >= 0 &&
                autoSplitWalls[indexWall] != null &&
                autoSplitWalls[indexWall].Tag != null &&
                autoSplitWalls[indexWall].Tag is TagModel &&
                !(autoSplitWalls[indexWall].Tag as TagModel).Wall_IsShow &&
                panelAllWall.Controls != null &&
                panelAllWall.Controls.Count > preWallIndex &&
                panelAllWall.Controls[preWallIndex] != null &&
                panelAllWall.Controls[preWallIndex] is WallPreview) // 大屏未上墙时
            {
                autoSplitWalls[indexWall].Show(); // a. 显示窗口
                autoSplitWalls[indexWall].PlayForm((panelAllWall.Controls[preWallIndex] as WallPreview).PanelCurrentList); // b. 播放视频
            }

            initializeStatistics(); // 重新统计
        }

        /// <summary>
        /// 关闭大屏
        /// </summary>
        /// <param name="indexWall">大屏序号</param>
        private void closeWall(int indexWall)
        {
            if (indexWall < 0)
                return;

            if (autoSplitWalls[indexWall] != null &&
                autoSplitWalls[indexWall].Tag != null &&
                autoSplitWalls[indexWall].Tag is TagModel &&
                (autoSplitWalls[indexWall].Tag as TagModel).Wall_IsShow) // 大屏已上墙时
            {
                autoSplitWalls[indexWall].CloseForm(); // 关闭大屏
            }

            initializeStatistics(); // 重新统计
        }

        /// <summary>
        /// 销毁主界面中对应大屏
        /// </summary>
        /// <param name="indexWall">大屏位置序号</param>
        private void removeFromAutoSplitWalls(int indexWall)
        {
            if (indexWall < 0)
                return;

            int preWallIndex; // 大屏所对应的预览模块序号


            if (Utilities.DebugModel)
            {
                preWallIndex = indexWall;
            }
            else
            {
                preWallIndex = indexWall - 1;
            }


            if (preWallIndex >= 0 &&
                panelAllWall.Controls.Count > preWallIndex &&
                panelAllWall.Controls[preWallIndex] != null &&
                panelAllWall.Controls[preWallIndex] is WallPreview &&
                (panelAllWall.Controls[preWallIndex] as WallPreview).Tag != null &&
                (panelAllWall.Controls[preWallIndex] as WallPreview).Tag is TagModel &&
                (panelAllWall.Controls[preWallIndex] as WallPreview).PanelCurrentList != null &&
                (panelAllWall.Controls[preWallIndex] as WallPreview).PanelCurrentList.Count > 0)
            {
                WallPreview preWall = panelAllWall.Controls[preWallIndex] as WallPreview;
                TagModel preWallTag = (panelAllWall.Controls[preWallIndex] as WallPreview).Tag as TagModel;

                if (panelEditWallDetail.Visible &&
                    preWallIndex == currentWallIndex) // 编辑详情界面可见且大屏显示与此界面对应时
                {
                    //realPlay(preWall.PanelCurrentList); // 1. 如果已设置过视频，播放对应的视频。注：这里是绿色的 Panel，PanelCurrentList 并未对应到每个 Panel 上。
                    return2WallPreview(); // 返回到预览模块界面
                    StopTimer(); // 未在大屏上显示，停止图标闪烁
                }
                preWall.IsShowWall = preWallTag.Wall_IsShow = false;

                autoSplitWalls[indexWall].Close();
                autoSplitWalls[indexWall] = null; // 2. 移除大屏
            }

            initializeStatistics(); // 重新统计
        }

        /// <summary>
        /// 保存大屏信息到数据库中
        /// </summary>
        /// <param name="indexWall">大屏位置序号</param>
        private void saveWallInfor(int indexWall)
        {
            if (indexWall < 0)
                return;

            // 1. 判断是否存在该大屏信息
            DataTable dtWall = dataOperation4VWMS.GetDataSet(
                string.Format(VWMSDal.QUERY_GET_ALLWALLDATA_BYWALLINDEX, indexWall), string.Empty,
                "db_VWMSConnectionString", string.Format("{0}.exe", Application.ProductName)).Tables[0];
            // 2. 删除该大屏信息
            if (dtWall.Rows.Count > 0)
            {
                dataOperation4VWMS.DeleteWallItem(indexWall);
            }
            // 3. 保存
            if (panelAllWall.Controls != null && panelAllWall.Controls.Count > 0 &&
                panelAllWall.Controls[indexWall] != null &&
                panelAllWall.Controls[indexWall] is WallPreview &&
                (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList != null &&
                (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList.Count > 0)
            {
                List<WallInformationModel> wallModelList = new List<WallInformationModel>(); // 保存要新增的列表
                WallInformationModel wallModel;
                TagModel singlePanelTag;

                foreach (Panel singlePanel in (panelAllWall.Controls[indexWall] as WallPreview).PanelCurrentList)
                {
                    if (singlePanel.Tag != null &&
                        singlePanel.Tag is TagModel)
                    {
                        singlePanelTag = singlePanel.Tag as TagModel;
                        wallModel = new WallInformationModel()
                        {
                            WallIndex = indexWall,
                            PanelIndex = singlePanelTag.Panel_Index,
                            IP = singlePanelTag.Driver_IP,
                            Port = singlePanelTag.Driver_Port,
                            Type = singlePanelTag.Driver_Type,
                            Channel = singlePanelTag.Panel_SelectedChannel,
                            UserName = singlePanelTag.Driver_User,
                            UserPwd = singlePanelTag.Driver_Password,
                        };

                        wallModelList.Add(wallModel); // 添加到列表中
                    }
                }

                dataOperation4VWMS.AddWallItem(wallModelList); // 添加到数据库中
            }
        }
        #endregion

        #region Panel 面板相关
        /// <summary>
        /// 返回到预览模块界面
        /// </summary>
        private void return2WallPreview()
        {
            panelEditWallDetail.Visible = false; // 编辑详情界面不可见
            panelAllWall.Visible = !panelEditWallDetail.Visible;

            panelOperation.SetNull2SelectedPanel(); // 未选中任何 Panel
            panelNewCurrentList = null; // 未记录任何最新的上墙分屏列表
        }

        /// <summary>
        /// 更新文字信息
        /// </summary>
        private void updateText()
        {
            WallPreview preview;
            int wallOKSum = 0, wallFaultySum = 0; // 记录该大屏的已成功设置个数，记录所有大屏已设置个数、所有大屏未设置个数
            int outWallOKSum, outWallFaultySum;

            for (int i = 0; i < wallCount; i++)
            {
                preview = panelAllWall.Controls[i] as WallPreview;
                if (int.TryParse(preview.OKSum, out outWallOKSum))
                    wallOKSum += outWallOKSum; // 总的已设置个数
                if (int.TryParse(preview.FaultySum, out outWallFaultySum))
                    wallFaultySum += outWallFaultySum; // 总的未设置个数
            }
            lbPanelInfo.Text = string.Format(MSG_PANELINFO, wallOKSum + wallFaultySum); // 总的视频窗口个数
            lbSetInfo.Text = string.Format(MSG_SETINFO, wallOKSum, wallFaultySum); // 总的已设置、未设置个数
        }
        #endregion

        #endregion

        #region 事件

        #region 主界面

        /// <summary>
        /// 初始化界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frm_Main_Load(object sender, EventArgs e)
        {
            try
            {
                #region 检查软件更新版本
                initializeWcfURL(); // 获取 WCF 地址
                try
                {
                    WebServiceProxy.Instance.GetLatestVersion(ProjectTypeEnum.VWMS.ToString(),
                        getLatestVersion_DataLoaded, null); // 获取最新版本号
                }
                catch (System.Exception ex)
                {
#if DEBUG
                    Debug.WriteLine(ex.Message);
#endif
                }                
                #endregion

                #region 更新自动升级程序
                
                #endregion

                #region GUID
                initializeProjectGUID(); // 获取本项目 GUID
                #endregion

                #region 数据库配置操作
                initializeDatabaseName(); // 获取数据库名称
                DataTable dtWall = initializeDatabase(); // 是否能正常连接到数据库

                if (dtWall == null)
                {
                    changeControlButtonDisenableStateWhenException("无法正常连接到数据库！");
                    return;
                }
                #endregion

                #region 加密锁操作
                bool isRegUser = initializeSoftKey(); // 判断是正式版用户还是试用版用户
                #endregion

                #region 系统初始化操作
                initializeFileAccessControl(); // 增加 mdb 文件修改权限
                if (initializeSystemTrialTimes(isRegUser)) // 是否达到试用次数，正式版用户继续使用
                    return;
                initializeDatabase4SystemInformation(); // 将最新数据保存到 SystemInformation
                if (isRegUser) // 若是正式版用户，备份数据库到指定位置（App.config）
                {
                    Utilities.BackupDatabase("BackupDirectory", Utilities.DatabaseName);
                }
                #endregion

                #region 布局操作
                initializeLayout();
                #endregion

                #region 文字操作
                if (!initializeText()) // 是否能执行上墙操作
                    return;
                #endregion

                #region TreeView 操作
                initializeTree();
                treeView1.ExpandAll(); // 默认展开所有结点
                #endregion

                #region 从数据库加载用户保存的大屏信息
                List<WallInformationModel> savedWallList = initializeWallLoaded(dtWall);
                #endregion

                #region 生成各个大屏预览模块
                if (savedWallList == null)
                    initializeWallPreview();
                else
                    initializeWallPreview(savedWallList);
                #endregion

                #region 上墙显示操作
                initializeAutoSplitWall();
                #endregion

                #region 统计界面操作
                initializeStatistics();
                #endregion
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
                changeControlButtonDisenableStateWhenException(ex.Message);
            }
        }

        /// <summary>
        /// 关闭窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frm_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("确定退出系统吗？", ConstantString.MSG_COMPANY, MessageBoxButtons.YesNo,
                MessageBoxIcon.Question, MessageBoxDefaultButton.Button1,
                MessageBoxOptions.DefaultDesktopOnly) != DialogResult.Yes)
            {
                e.Cancel = true;
                return;
            }
        }

        #endregion

        #region 按钮

        /// <summary>
        /// 退出系统
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            WallPreview preWall;
            TagModel preWallPanelTag;

            if (panelAllWall.Controls != null && panelAllWall.Controls.Count > 0)
            {
                for (int i = 0; i < panelAllWall.Controls.Count; i++)
                {
                    if (panelAllWall.Controls[i] != null &&
                        panelAllWall.Controls[i] is WallPreview &&
                        (panelAllWall.Controls[i] as WallPreview).PanelCurrentList != null &&
                        (panelAllWall.Controls[i] as WallPreview).PanelCurrentList.Count > 0 &&
                        (panelAllWall.Controls[i] as WallPreview).Tag != null &&
                        (panelAllWall.Controls[i] as WallPreview).Tag is TagModel)
                    {
                        preWall = panelAllWall.Controls[i] as WallPreview;
                        for (int j = 0; j < preWall.PanelCurrentList.Count; j++)
                        {
                            if (preWall.PanelCurrentList[j] != null &&
                                preWall.PanelCurrentList[j].Tag != null &&
                                preWall.PanelCurrentList[j].Tag is TagModel &&
                                (preWall.PanelCurrentList[j].Tag as TagModel).Driver_Instance != null)
                            {
                                preWallPanelTag = preWall.PanelCurrentList[j].Tag as TagModel;
                                preWallPanelTag.Driver_Instance.CleanUp(); // 循环释放 SDK 资源
                            }
                        }
                    }
                }
            }

            Application.Exit(); // 退出程序
        }

        /// <summary>
        /// 识别
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnIdentification_Click(object sender, EventArgs e)
        {
            #region Timer
            Timer timerIdentification = new Timer(); // 计时器
            timerIdentification.Interval = 3000; // 单位：毫秒
            timerIdentification.Tick += (s, arg) =>
            {
                btnIdentification.Enabled = true;
                timerIdentification.Stop();
            };
            timerIdentification.Start();
            #endregion

            try
            {
                btnIdentification.Enabled = false;
                // 识别大屏，从下标 0 开始，0：表示主监视器
                for (int i = 0; i < Screen.AllScreens.Length; i++)
                {
                    frm_IdentificationWall idWall = new frm_IdentificationWall()
                    {
                        StartPosition = FormStartPosition.Manual,
                        Location = new Point(Screen.AllScreens[i].Bounds.Left,
                            Screen.AllScreens[i].Bounds.Top),

                        WallNo = i.ToString(), // 从 0 开始
                        Text = string.Format("识别大屏 {0}", i), // 标题
                    };

                    idWall.Show(); // 显示大屏序号
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 查看注册码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShowMachineNum_Click(object sender, EventArgs e)
        {
            frm_RegCode regCode = new frm_RegCode();
            regCode.ShowDialog();
        }

        /// <summary>
        /// 重置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReset_Click(object sender, EventArgs e)
        {
            try
            {
                if (MessageBox.Show("确定要恢复初始值吗？", ConstantString.MSG_COMPANY, MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question, MessageBoxDefaultButton.Button1,
                    MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes)
                {
                    // 1. 关闭所有大屏
                    btnModify.PerformClick();

                    // 2. 还原所有设置
                    initializeLayout();
                    if (!initializeText())
                        return;
                    initializeWallPreview();
                    initializeAutoSplitWall();
                    initializeStatistics();
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 关闭所有大屏后可修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnModify_Click(object sender, EventArgs e)
        {
            try
            {
                // 1. 停止播放最大化 Panel
                stopMaxScreenRealPlay();

                // 2. 若编辑详情界面可见，且有视频正在播放【即未上墙显示时】，停止所有正在播放的视频
                if (panelEditWallDetail.Visible &&
                    currentWallIndex >= 0 && panelAllWall.Controls != null &&
                    panelAllWall.Controls.Count > currentWallIndex &&
                    panelAllWall.Controls[currentWallIndex] != null &&
                    panelAllWall.Controls[currentWallIndex] is WallPreview &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag is TagModel &&
                    !((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    stopRealPlay(panelNewCurrentList);
                }

                // 3. 修改按钮与图标状态
                for (int i = 0; i < panelAllWall.Controls.Count; i++)
                {
                    WallPreview preWall = panelAllWall.Controls[i] as WallPreview;
                    if (preWall != null)
                    {
                        preWall.IsShowWall = (preWall.Tag as TagModel).Wall_IsShow = false;
                    }
                }

                // 4. 关闭所有大屏
                if (autoSplitWalls != null)
                {
                    for (int i = initialWallIndex; i < autoSplitWalls.Length; i++)
                    {
                        closeWall(i); // 关闭大屏
                    }
                }

                // 5. 将所有大屏的所有 Panel_RealPlayHandle 置为空
                setNonPanelRealPlayHandle4AllWall();

                // 6. 设置相关界面可见性
                return2WallPreview(); // 返回到预览模块界面

                // 7. 重新统计
                initializeStatistics();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 上墙显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShow_Click(object sender, EventArgs e)
        {
            try
            {
                // 1. 停止播放最大化 Panel
                stopMaxScreenRealPlay();

                // 2. 若编辑详情界面可见，且有视频正在播放【即未上墙显示时】，停止所有正在播放的视频
                if (panelEditWallDetail.Visible &&
                    currentWallIndex >= 0 && panelAllWall.Controls != null &&
                    panelAllWall.Controls.Count > currentWallIndex &&
                    panelAllWall.Controls[currentWallIndex] != null &&
                    panelAllWall.Controls[currentWallIndex] is WallPreview &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag is TagModel &&
                    !((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    autoSaveAndStopRealPlay(); // 自动保存并停止播放
                }

                // 3. 修改按钮与图标状态
                for (int i = 0; i < panelAllWall.Controls.Count; i++)
                {
                    WallPreview preWall = panelAllWall.Controls[i] as WallPreview;
                    if (preWall != null)
                    {
                        preWall.IsShowWall = (preWall.Tag as TagModel).Wall_IsShow = true;
                    }
                }

                // 4. 所有大屏上墙显示
                if (autoSplitWalls != null)
                {
                    for (int i = initialWallIndex; i < autoSplitWalls.Length; i++)
                    {
                        showWall(i); // 上墙显示
                    }
                }

                // 5. 设置相关界面可见性
                return2WallPreview(); // 返回到预览模块界面

                // 6. 重新统计
                initializeStatistics();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        #region Tree

        /// <summary>
        /// 双击叶子结点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseDoubleClick(object sender,
            TreeNodeMouseClickEventArgs e)
        {
            try
            {
                if (treeView1.SelectedNode == null ||
                    (treeView1.SelectedNode != null && treeView1.SelectedNode.Level != 2)) // 只有叶子结点有效
                    return;

                if (panelMaxScreen.Visible)
                {
                    MessageBox.Show("请在视频窗口最小化时进行设置!", ConstantString.MSG_COMPANY);
                    return;
                }

                int outChannel;
                if (PanelOperation.SelectedPanel != null &&
                    PanelOperation.SelectedPanel.Tag != null &&
                    PanelOperation.SelectedPanel.Tag is TagModel &&
                    treeView1.SelectedNode.Tag != null &&
                    treeView1.SelectedNode.Tag is TagModel &&
                    (treeView1.SelectedNode.Tag as TagModel).Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace((treeView1.SelectedNode.Tag as TagModel).Driver_LoginID) &&
                    !string.IsNullOrWhiteSpace((treeView1.SelectedNode.Tag as TagModel).Panel_SelectedChannel) &&
                    int.TryParse((treeView1.SelectedNode.Tag as TagModel).Panel_SelectedChannel, out outChannel)) // 先停止正在播放的视频
                {
                    TagModel panelTag = PanelOperation.SelectedPanel.Tag as TagModel;
                    TagModel treeTag = treeView1.SelectedNode.Tag as TagModel;

                    if (panelTag.Driver_Instance != null &&
                        !string.IsNullOrWhiteSpace(panelTag.Panel_RealPlayHandle))
                    {
                        if (panelTag.Driver_Instance.StopRealPlay(panelTag.Panel_RealPlayHandle)) // 停止实时监控，需要传递实时监控句柄
                            panelTag.Panel_RealPlayHandle = string.Empty;
                        else
                        {
                            MessageBox.Show(SurveillanceUtilities.STOP_REALPLAY_FAILURE, ConstantString.MSG_COMPANY);
                            return;
                        }
                    }

                    string pRealPlayHandle = treeTag.Driver_Instance.RealPlay(treeTag.Driver_LoginID,
                        outChannel, PanelOperation.SelectedPanel.Handle); // 只取数据不播放
                    treeTag.Panel_RealPlayHandle = pRealPlayHandle;
                    treeTag.Panel_Index = panelTag.Panel_Index; // 记录视频窗口序号

                    Utilities.CopyObject(treeTag, panelTag);
                    SurveillanceUtilities.SetPanelTooltip(PanelOperation.SelectedPanel,
                        panelTag, toolTip, false, Color.LimeGreen);  // 设置 Tooltip
                    focus2NextPanel(); // 将焦点自动循环移动到下一个视频窗口中
                }
                else
                    MessageBox.Show("没有选择视频窗口!", ConstantString.MSG_COMPANY);
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        #region 菜单

        /// <summary>
        /// 右键菜单的显示【Tree 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cMStrip_Opening(object sender, CancelEventArgs e)
        {
            if (treeView1.SelectedNode == null || treeView1.SelectedNode.Level == 2 ||
                treeView1.SelectedNode.Tag == null)
            {
                e.Cancel = true;
                return;
            }

            if (treeView1.SelectedNode.Level == 0) // 根
            {
                tSMItem1.Enabled = false; // 设备登录
                tSMItem2.Enabled = false; // 注销设备
                tSMItem3.Enabled = true; // 添加设备
            }
            else if (treeView1.SelectedNode.Level == 1) // 设备
            {
                tSMItem1.Enabled = false;
                tSMItem2.Enabled = true;
                tSMItem3.Enabled = false;
                if (!(treeView1.SelectedNode.Tag as TagModel).Driver_IsLogin)
                {
                    tSMItem1.Enabled = true;
                    tSMItem2.Enabled = false;
                }
            }
        }

        /// <summary>
        /// 设备登陆【Tree 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tSMItem1_Click(object sender, EventArgs e)
        {
            try
            {
                if (treeView1.SelectedNode.Tag != null)
                {
                    NetDeviceInfoStruct deviceInfo; // 设备用户信息获得
                    int error = 0;
                    string pLoginID;

                    TagModel nodeTag = treeView1.SelectedNode.Tag as TagModel;
                    pLoginID = nodeTag.Driver_Instance.Login(nodeTag.Driver_IP, ushort.Parse(nodeTag.Driver_Port),
                        nodeTag.Driver_User,
                        EncryptAlgorithmHelper.Decrypt2(nodeTag.Driver_Password, Utilities.MachineCode),
                        out deviceInfo, out error); // 设备用户登录
                    if (!string.IsNullOrWhiteSpace(pLoginID) && deviceInfo.byChanNum > 0)
                    {
                        nodeTag.Driver_IsLogin = true; // 设备已登录
                        nodeTag.Driver_LoginID = pLoginID;
                        string[] exceptChannels = null;
                        bool isExcept = false; // 表示是否为排除的通道号

                        if (!string.IsNullOrWhiteSpace(nodeTag.Driver_ExceptChannel))
                        {
                            exceptChannels = nodeTag.Driver_ExceptChannel.Split(','); // 得到所有排除的通道序列
                        }

                        for (int i = 0; i < deviceInfo.byChanNum; i++)
                        {
                            isExcept = false; // 未排除
                            if (exceptChannels != null && exceptChannels.Length > 0)
                            {
                                foreach (string channel in exceptChannels) // 排除通道号
                                {
                                    if (channel.Equals((i + 1).ToString()))
                                        isExcept = true;
                                }
                            }

                            if (isExcept)
                                continue;

                            TreeNode leafChannel = new TreeNode()
                            {
                                Name = i.ToString(),
                                Text = string.Format("通道{0}", i + 1),
                                Tag = new TagModel()
                                {
                                    Driver_IsLogin = nodeTag.Driver_IsLogin,
                                    Driver_Instance = nodeTag.Driver_Instance,
                                    Driver_IP = nodeTag.Driver_IP,
                                    Driver_LoginID = nodeTag.Driver_LoginID,
                                    Driver_Password = nodeTag.Driver_Password,
                                    Driver_Port = nodeTag.Driver_Port,
                                    Driver_Type = nodeTag.Driver_Type,
                                    Driver_User = nodeTag.Driver_User,
                                    Panel_SelectedChannel = i.ToString(),
                                },
                            };

                            treeView1.SelectedNode.Nodes.Add(leafChannel);
                        }
                    }
                    else
                    {
                        MessageBox.Show(nodeTag.Driver_Instance.GetLastOperationInfo(SurveillanceUtilities.ERR_INFO_FORMAT_STYLE), 
                            ConstantString.MSG_COMPANY); // 报最后一次操作的错误信息
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 注销设备【Tree 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tSMItem2_Click(object sender, EventArgs e)
        {
            try
            {
                if (treeView1.SelectedNode.Tag != null)
                {
                    TagModel nodeTag = treeView1.SelectedNode.Tag as TagModel;
                    if (nodeTag.Driver_Instance.Logout(nodeTag.Driver_LoginID))
                    {
                        // 1. 设备未登录
                        nodeTag.Driver_IsLogin = false;

                        // 2. 去 Tag 中的 loginID
                        nodeTag.Driver_LoginID = string.Empty;

                        // 3. 清空所有通道
                        treeView1.SelectedNode.Nodes.Clear();

                        // 4. 提示成功
                        MessageBox.Show("注销成功", ConstantString.MSG_COMPANY);
                    }
                    else
                        MessageBox.Show(nodeTag.Driver_Instance.GetLastOperationInfo(SurveillanceUtilities.ERR_INFO_FORMAT_STYLE), 
                            ConstantString.MSG_COMPANY); // 报最后一次操作的错误信息
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 添加设备【Tree 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tSMItem3_Click(object sender, EventArgs e)
        {
            try
            {
                frm_DataBase frmdatabase = new frm_DataBase(initializeTree);
                frmdatabase.ShowDialog();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }


        /// <summary>
        /// 右键菜单的显示【Panel 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cMPanelStrip_Opening(object sender, CancelEventArgs e)
        {
            if (PanelOperation.SelectedPanel == null || PanelOperation.SelectedPanel.Tag == null ||
                !(PanelOperation.SelectedPanel.Tag is TagModel) ||
                string.IsNullOrWhiteSpace((PanelOperation.SelectedPanel.Tag as TagModel).Panel_RealPlayHandle))
            {
                e.Cancel = true;
                return;
            }
        }

        /// <summary>
        /// 关闭当前视频【Panel 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tSMPanelItem1_Click(object sender, EventArgs e)
        {
            stopPanelRealPlay(PanelOperation.SelectedPanel); // 停止当前视频
        }

        /// <summary>
        /// 关闭所有视频【Panel 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tSMPanelItem2_Click(object sender, EventArgs e)
        {
            if (panelNewCurrentList != null &&
                panelNewCurrentList.Count > 0)
            {
                foreach (Panel singlePanel in panelNewCurrentList)
                {
                    stopPanelRealPlay(singlePanel); // 停止当前视频
                }

                panelSplitScreen.Refresh();
            }
        }

        #endregion

        #region 分屏

        /// <summary>
        /// 1 画面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnScreen1_Click(object sender, EventArgs e)
        {
            try
            {
                if (currentWallIndex < 0)
                    return;

                changeScreenButtonEnableState(true);
                (sender as Button).Enabled = false;

                panelSplitScreen.SuspendLayout();
                this.SuspendLayout();
                if (panelNewCurrentList == null)
                    panelNewCurrentList = (panelAllWall.Controls[currentWallIndex] as WallPreview).PanelCurrentList;

                if ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag is TagModel &&
                    ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    panelOperation.SplitScreens(1, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, true, toolTip);
                }
                else
                {
                    panelNewCurrentList = panelOperation.SplitScreens(1, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, false, toolTip);
                }

                panelSplitScreen.ResumeLayout();
                this.ResumeLayout();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 4 画面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnScreen4_Click(object sender, EventArgs e)
        {
            try
            {
                if (currentWallIndex < 0)
                    return;

                changeScreenButtonEnableState(true);
                (sender as Button).Enabled = false;

                panelSplitScreen.SuspendLayout();
                this.SuspendLayout();
                if (panelNewCurrentList == null)
                    panelNewCurrentList = (panelAllWall.Controls[currentWallIndex] as WallPreview).PanelCurrentList;

                if ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag is TagModel &&
                    ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    panelOperation.SplitScreens(4, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, true, toolTip);
                }
                else
                {
                    panelNewCurrentList = panelOperation.SplitScreens(4, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, false, toolTip);
                }

                panelSplitScreen.ResumeLayout();
                this.ResumeLayout();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 9 画面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnScreen9_Click(object sender, EventArgs e)
        {
            try
            {
                if (currentWallIndex < 0)
                    return;

                changeScreenButtonEnableState(true);
                (sender as Button).Enabled = false;

                panelSplitScreen.SuspendLayout();
                this.SuspendLayout();
                if (panelNewCurrentList == null)
                    panelNewCurrentList = (panelAllWall.Controls[currentWallIndex] as WallPreview).PanelCurrentList;

                if ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag is TagModel &&
                    ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    panelOperation.SplitScreens(9, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, true, toolTip);
                }
                else
                {
                    panelNewCurrentList = panelOperation.SplitScreens(9, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, false, toolTip);
                }

                panelSplitScreen.ResumeLayout();
                this.ResumeLayout();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 16 画面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnScreen16_Click(object sender, EventArgs e)
        {
            try
            {
                if (currentWallIndex < 0)
                    return;

                changeScreenButtonEnableState(true);
                (sender as Button).Enabled = false;

                panelSplitScreen.SuspendLayout();
                this.SuspendLayout();
                if (panelNewCurrentList == null)
                    panelNewCurrentList = (panelAllWall.Controls[currentWallIndex] as WallPreview).PanelCurrentList;

                if ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag is TagModel &&
                    ((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    panelOperation.SplitScreens(16, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, true, toolTip);
                }
                else
                {
                    panelNewCurrentList = panelOperation.SplitScreens(16, panelSplitScreen, panelMaxScreen,
                        panelNewCurrentList, changeGroupButtonState, false, toolTip);
                }

                panelSplitScreen.ResumeLayout();
                this.ResumeLayout();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSaveWall_Click(object sender, EventArgs e)
        {
            try
            {
                if (currentWallIndex < 0)
                    return;

                WallPreview preview = panelAllWall.Controls[currentWallIndex] as WallPreview;
                // 1. 更新预览模块，并改变预览模块中的分屏颜色
                panelOperationExt.IsHideClickEvent = panelOperationExt.IsHideBorder = true; // 隐藏边框颜色、隐藏点击事件
                panelOperationExt.SplitScreens(panelNewCurrentList.Count, preview.TablePanel,
                    null, preview.ShowButtons, panelNewCurrentList, true, toolTip); // 重新创建预览模块的新分屏
                // 2. 大屏分屏列表中保存最新分屏信息
                preview.PanelCurrentList = panelNewCurrentList;
                // 3. 修改文字提示信息，包括大屏与预览模块
                int okSum = 0; // 记录该修改大屏的已设置个数
                foreach (Panel singlePanel in panelNewCurrentList)
                {
                    if (singlePanel.Tag != null &&
                        singlePanel.Tag is TagModel &&
                        !string.IsNullOrWhiteSpace((singlePanel.Tag as TagModel).Driver_IP) &&
                        !string.IsNullOrWhiteSpace((singlePanel.Tag as TagModel).Panel_SelectedChannel) &&
                        !string.IsNullOrWhiteSpace((singlePanel.Tag as TagModel).Panel_RealPlayHandle))
                        okSum += 1; // 已设置个数
                }
                preview.OKSum = okSum.ToString();
                preview.FaultySum = (panelNewCurrentList.Count - okSum).ToString();

                updateText(); // 更新文字信息
                initializeStatistics(); // 重新统计
                saveWallInfor(currentWallIndex); // 保存信息到数据库中
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 保存并返回
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSaveAndReturnWall_Click(object sender, EventArgs e)
        {
            try
            {
                btnSaveWall.PerformClick(); // 保存
                btnReturnWall.PerformClick(); // 返回
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 返回
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReturnWall_Click(object sender, EventArgs e)
        {
            try
            {
                stopMaxScreenRealPlay(); // 停止播放最大化 Panel
                // 未上墙显示时，停止所有正在播放的视频
                if (currentWallIndex >= 0 &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    !((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    stopRealPlay(panelNewCurrentList);
                }

                // 将当前大屏的所有 Panel_RealPlayHandle 置为空
                setNonPanelRealPlayHandle4CurrentWall(currentWallIndex);
                return2WallPreview(); // 返回到预览模块界面
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 上一个
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPreviousWall_Click(object sender, EventArgs e)
        {
            try
            {
                btnPreviousWall.Enabled = btnNextWall.Enabled = true;
                // 未上墙显示时，停止所有正在播放的视频
                if (currentWallIndex >= 0 &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    !((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    autoSaveAndStopRealPlay(); // 自动保存并停止播放
                }

                showEditWallDetail(--currentWallIndex); // 向前显示编辑详情界面
                if (currentWallIndex <= 0)
                    btnPreviousWall.Enabled = false;
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 下一个
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNextWall_Click(object sender, EventArgs e)
        {
            try
            {
                btnPreviousWall.Enabled = btnNextWall.Enabled = true;
                // 未上墙显示时，停止所有正在播放的视频
                if (currentWallIndex >= 0 &&
                    (panelAllWall.Controls[currentWallIndex] as WallPreview).Tag != null &&
                    !((panelAllWall.Controls[currentWallIndex] as WallPreview).Tag as TagModel).Wall_IsShow)
                {
                    autoSaveAndStopRealPlay(); // 自动保存并停止播放
                }

                showEditWallDetail(++currentWallIndex); // 向后显示编辑详情界面
                if (currentWallIndex >= panelAllWall.Controls.Count - 1)
                    btnNextWall.Enabled = false;
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 双击最大化视频窗口，还原为分屏模式
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void panelMaxScreen_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                panelSplitScreen.Visible = true;
                panelMaxScreen.Visible = !panelSplitScreen.Visible;
                SurveillanceUtilities.StopAndPlay(panelMaxScreen, PanelOperation.SelectedPanel);

                // d. 执行双击后的相关操作
                changeScreenButtonEnableState(false);
                switch (panelSplitScreen.Controls.Count)
                {
                    case 1:
                        btnScreen1.Enabled = false;
                        break;
                    case 4:
                        btnScreen4.Enabled = false;
                        break;
                    case 9:
                        btnScreen9.Enabled = false;
                        break;
                    case 16:
                        btnScreen16.Enabled = false;
                        break;


                    default:
                        break;
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        #endregion

        #region 注册到外部的事件

        /// <summary>
        /// GetLatestVersion
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void getLatestVersion_DataLoaded(object sender,
            GetLatestVersionCompletedEventArgs e)
        {
            WebServiceProxy.Instance.RemoveGetLatestVersionCompleted(getLatestVersion_DataLoaded);

            try
            {
                
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        #region Override

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case Win32.WM_DEVICECHANGE:
                    keyOperation.OnDeviceChange(ref m, false);
                    break;
            }

            base.WndProc(ref m);
        }

        #endregion
    }
}
